package com.chineseall.rebirth.bridge.service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import jmind.core.lang.Page;
import jmind.core.lang.ScoreValue;
import jmind.core.util.DataUtil;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chineseall.rebirth.api.RebirthApiFactory;
import com.chineseall.rebirth.api.helper.CommentConst;
import com.chineseall.rebirth.api.helper.CommentConst.CommentType;
import com.chineseall.rebirth.api.helper.CommentConst.IComment;
import com.chineseall.rebirth.api.helper.CommentConst.SettingCode;
import com.chineseall.rebirth.api.helper.CommentHelper;
import com.chineseall.rebirth.api.helper.Const;
import com.chineseall.rebirth.api.pojo.CommentManageLog;
import com.chineseall.rebirth.api.pojo.CommentReply;
import com.chineseall.rebirth.api.pojo.CommentTopic;
import com.chineseall.rebirth.api.pojo.User;
import com.chineseall.rebirth.api.service.ICommentService;
import com.chineseall.rebirth.api.service.IManagerCommentService;
import com.chineseall.rebirth.api.service.IUserService;
import com.chineseall.rebirth.bridge.pojo.Book;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

@Service
public class CommentService {

    @Resource
    private UserAggregationService userAggregationService;
    @Resource
    private ZedisService zedisService;
    private IUserService userService = RebirthApiFactory.getFactory().getApiService(IUserService.class);
    private ICommentService service = RebirthApiFactory.getFactory().getApiService(ICommentService.class);
    private IManagerCommentService managerService = RebirthApiFactory.getFactory().getApiService(
            IManagerCommentService.class);

    // 解析书
    private String parseBook(String content) {
        Set<String> names = CommentHelper.getBookNames(content);
        if (names.size() > 0) {
            for (String name : names) {
                Book book = zedisService.getBookByName(name);
                if (book != null) {
                    content = content.replace("《" + name + "》", "[book=" + name + ":" + book.getId() + "]");
                }
            }
        }
        return content;
    }

    /**
     * 权限验证
     * 2014-4-3 
     * @param user
     * @param bookId
     * @return
     */
    private String canReply(User user, int bookId) {
        // 用户信息
        if (user.hasStatus(Const.STATUS_LOGIN) || user.hasStatus(Const.STATUS_COMMENT)) {
            return "用户被禁言";
        }
        // 本书对用户禁言
        String setting = managerService.getGroupSetting(bookId, CommentConst.COMMENT_TYPE_BOOK,
                SettingCode.forbidden_user);
        if (!DataUtil.isEmpty(setting)) {
            if (setting.matches(".*\"user_id\":" + user.getCid() + "[,}].*")) {
                return "此书用户被禁言";
            }
        }

        return null;

    }

    private void fillTopic(List<CommentTopic> result) {
        if (DataUtil.isEmpty(result))
            return;
        int bookId = result.get(0).getResourceId();
        Set<Integer> cids = Sets.newHashSet();
        Set<Integer> authorReplyId = Sets.newHashSet();
        for (CommentTopic topic : result) {
            cids.add(topic.getUserId());
            cids.add(topic.getLastReplyUserId());
            authorReplyId.add(topic.getLastAuthorReplyId());
        }
        cids.remove(null);
        cids.remove(0);
        authorReplyId.remove(null);
        authorReplyId.remove(0);
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        Map<Integer, CommentReply> replys = null;
        if (authorReplyId.isEmpty()) {
            replys = Collections.emptyMap();
        } else {
            replys = service.getReply(bookId, authorReplyId);
        }

        for (CommentTopic topic : result) {
            int cid = topic.getUserId();
            Map<String, Object> map = views.get(cid);
            if (map != null) { // 主题
                topic.getMarks().putAll(map);
                Map<String, Object> fans = userAggregationService.getFans(topic.getResourceId(),
                        (Integer) map.get("userId"));
                if (!DataUtil.isEmpty(fans))
                    topic.getMarks().putAll(fans);
                // 最后回复人
                if (topic.getLastReplyUserId() != null && topic.getLastReplyUserId() > 0) {
                    Map<String, Object> lastReplyUser = views.get(topic.getLastReplyUserId());
                    if (lastReplyUser != null) {
                        topic.getMarks().put("lastReplyUser", lastReplyUser);
                    }
                }
                // 最新作者回复
                if (topic.getLastAuthorReplyId() > 0) {
                    CommentReply reply = replys.get(topic.getLastAuthorReplyId());
                    if (reply != null && reply.getIsDeleted() == 0) {
                        Map<String, Object> m = Maps.newHashMap();
                        m.put("content", reply.getContent());
                        m.put("creationDate", reply.getCreationDate());
                        topic.getMarks().put("lastAuthorReply", m);
                    }

                }
            }

        }

    }

    private void filling(List<CommentTopic> result) {
        if (DataUtil.isEmpty(result))
            return;
        Set<Integer> cids = Sets.newHashSet();
        for (CommentTopic topic : result) {
            cids.add(topic.getUserId());
        }
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        for (CommentTopic topic : result) {
            int cid = topic.getUserId();
            Map<String, Object> map = views.get(cid);
            if (map != null) {
                topic.getMarks().putAll(map);
                Map<String, Object> fans = userAggregationService.getFans(topic.getResourceId(),
                        (Integer) map.get("userId"));
                if (!DataUtil.isEmpty(fans))
                    topic.getMarks().putAll(fans);
            }

        }

    }

    private void fillingMLog(List<CommentManageLog> result) {
        if (DataUtil.isEmpty(result))
            return;
        Set<Integer> cids = Sets.newHashSet();
        for (CommentManageLog mlog : result) {
            cids.add(mlog.getUserId());
        }
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        for (CommentManageLog mlog : result) {
            int cid = mlog.getUserId();
            Map<String, Object> map = views.get(cid);
            if (map != null) {
                mlog.getMarks().putAll(map);
            }

        }

    }

    /**
     * 
     * 2014-3-10 
     * @param uid 17k 本地id
     * @param bookId  书i的
     * @param title 标题
     * @param content 内容 ，大于300 是长评
     * @param childResourceId 章节i的
     * @param userType  用户类型 0：www， 1：wap，2：Android，3：ios
     * @param isAuthor 是否作者
     * @param childResouceInfo 章节信息
     * @param ip
     * @param device_info 设备信息
     */
    public String puplishComment(int uid, int bookId, String title, String content, int userType, int childResourceId,
            String childResouceInfo, String ip, String device_info) {
        User user = userService.getByUid(uid);
        String msg = canReply(user, bookId);
        if (msg != null)
            return msg;
        Book book = zedisService.getBook(bookId);
        if (book == null)
            return "此书不存在";
        int isAuthor = book.getAuthor_id() == uid ? 1 : 0;
        content = parseBook(content);
        service.puplishComment(user.getCid(), bookId, CommentConst.COMMENT_TYPE_BOOK, title, content, userType,
                isAuthor, childResourceId, childResouceInfo, ip, device_info);

        return "评论成功!";

    }

    /**
     * 
     * 2014-3-12 
     * @param cid
     * @param bookId
     * @param topicId 评论主题id
     * @param content 内容
     * @param replyId 回应的回应id, 默认0
     * @param userType 用户类型
     * @param isAuthor 1 作者
     * @param ip
     * @param device_info
     */
    public String puplishReply(int uid, int bookId, int topicId, String content, int userType, int replyId, String ip,
            String device_info) {
        User user = userService.getByUid(uid);
        String msg = canReply(user, bookId);
        if (msg != null)
            return msg;
        // 回应，查询是否锁帖
        CommentTopic topic = service.getCommentTopic(topicId, false);
        if (topic.getIsEnabled() == 0)
            return "被锁帖了";

        Book book = zedisService.getBook(bookId);
        if (book == null)
            return "此书不存在";

        int isAuthor = book.getAuthor_id() == uid ? 1 : 0;
        service.puplishReply(user.getCid(), bookId, CommentConst.COMMENT_TYPE_BOOK, topicId, topic.getUserId(),
                content, replyId, userType, isAuthor, ip);

        return "回应成功!";

    }

    /**
     * 
     * 2014-3-12 
     * @param bookId 书id
     * @param commentType 0{}全部，1：作者，2：长评，3：精华
     * @param order 1：按时间倒序 2： 按reply_cout
     * @param page
     * @param pagesize
     * @return
     */
    public Page<CommentTopic> getTopicList(int bookId, CommentType commentType, int order, Page<CommentTopic> page) {
        page = service.getTopicList(bookId, CommentConst.COMMENT_TYPE_BOOK, commentType, order, page);
        fillTopic(page.getResult());
        return page;
    }

    public Page<CommentReply> getReplyList(int topicId, CommentType commentType, int order, Page<CommentReply> page) {
        page = service.getReplyList(topicId, commentType, order, page);
        if (page.getResult().size() > 0) {
            Set<Integer> cids = Sets.newHashSet();
            for (CommentReply reply : page.getResult()) {
                cids.add(reply.getReplyUserId());
            }
            Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
            for (CommentReply reply : page.getResult()) {
                int cid = reply.getReplyUserId();
                Map<String, Object> map = views.get(cid);
                if (map != null) {
                    reply.getMarks().putAll(map);
                }

            }
        }
        return page;
    }

    public CommentTopic getTopic(int topicId) {
        CommentTopic topic = service.getCommentTopic(topicId, true);
        if (topic != null)
            filling(Lists.newArrayList(topic));
        return topic;
    }

    /**
     * 锁帖列表
     * 2014-3-12 
     * @param bookId
     * @param page
     * @param pagesize
     * @return
     */
    public Page<CommentTopic> getDisableTopicList(int bookId, Page<CommentTopic> page) {
        page = managerService.getDisableTopicList(bookId, CommentConst.COMMENT_TYPE_BOOK, page);
        filling(page.getResult());
        return page;
    }

    /**
     * 
     * 2014-3-12 
     * @param bookId
     * @param page
     * @param pagesize
     * @param state 1：正常2：回收站3：删除
     * @return
     */
    public Page<CommentTopic> getTopicListByState(int bookId, int state, Page<CommentTopic> page) {
        page = managerService.getTopicListByState(bookId, CommentConst.COMMENT_TYPE_BOOK, state, page);
        filling(page.getResult());
        return page;
    }

    public Page<CommentTopic> listIComment(Page<CommentTopic> page, int cid, IComment iComment) {
        page = service.listIComment(page, cid, iComment);
        List<CommentTopic> result = page.getResult();
        if (result.isEmpty())
            return page;
        Set<Integer> cids = Sets.newHashSet();
        Set<Integer> bookIds = Sets.newHashSet();
        for (CommentTopic topic : result) {
            cids.add(topic.getUserId());
            bookIds.add(topic.getResourceId());
        }
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        Map<Integer, String> bookNames = zedisService.getBookNames(bookIds);
        for (CommentTopic topic : result) {
            Map<String, Object> map = views.get(topic.getUserId());
            if (map != null) {
                topic.getMarks().putAll(map);
                topic.mark("bookName", bookNames.get(topic.getResourceId()));
            }

        }
        return page;
    }

    /**
     * 粉丝评论排行榜
     * 2014-4-11 
     * @param bookId
     * @param count
     * @return
     */
    public List<Map<String, Object>> getFansWaterTop(int bookId, int count) {
        List<ScoreValue<String>> waterTop = service.getFansWaterTop(bookId, count);
        List<Integer> cids = Lists.newArrayList();
        for (ScoreValue<String> s : waterTop) {
            cids.add(DataUtil.toInt(s.getValue()));
        }
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        List<Map<String, Object>> list = Lists.newArrayList();
        for (int i = 0; i < cids.size(); i++) {
            Map<String, Object> map = views.get(cids.get(i));
            if (map != null) {
                map.put("score", waterTop.get(i).getScore());
                Map<String, Object> fans = userAggregationService.getFans(bookId, (Integer) map.get("userId"));
                map.putAll(fans);
                list.add(map);
            }
        }
        return list;
    }

    /**
     * 获取管理员详细列表
     * @param bookId
     * @return
     */
    public List<Map<String, Object>> getAdmin(int bookId) {
        List<Integer> cids = managerService.getAdminCids(bookId);
        if (cids.isEmpty())
            return Collections.emptyList();
        return Lists.newArrayList(userAggregationService.getViews(cids).values());
    }

    /**
     * 是否是管理员
     * @param bookId
     * @param uid
     * @return
     */
    public boolean isAdmin(int bookId, User user) {
        return managerService.getAdminCids(bookId).contains(user.getCid())
                || user.getUid() == zedisService.getBook(bookId).getAuthor_id();
    }

    /**
     * 获取申请管理员人员详细列表
     * @param bookId
     * @return
     */
    public List<Map<String, Object>> getAdminApplications(int bookId) {
        List<Integer> cids = managerService.getAdminApplications("cid", bookId, CommentConst.ADMIN_APPLAY);
        if (cids.size() == 0)
            return Lists.newArrayList();
        return Lists.newArrayList(userAggregationService.getViews(cids).values());
    }

    /**
     * 获取禁言用户
     * 2014-4-3 
     * @param user
     * @param bookId
     * @return
     */
    public List<Map<String, Object>> getForbiddenUser(int bookId) {
        String setting = managerService.getGroupSetting(bookId, CommentConst.COMMENT_TYPE_BOOK,
                SettingCode.forbidden_user);
        JSONArray settings = JSON.parseArray(setting);
        JSONObject s = null;
        List<Map<String, Object>> fusers = Lists.newArrayList();
        List<Integer> cids = Lists.newArrayList();
        Map<String, Object> fuser = null;
        int cid = -1;
        for (int i = 0; i < settings.size(); i++) {
            fuser = Maps.newHashMap();
            s = settings.getJSONObject(i);
            cid = s.getIntValue("user_id");
            cids.add(cid);
            fuser.put("cid", cid);
            fuser.put("start_date", s.getString("start_date"));
            fuser.put("end_date", s.getString("end_date"));
            fusers.add(fuser);
        }
        Map<Integer, Map<String, Object>> views = userAggregationService.getViews(cids);
        for (Map<String, Object> f : fusers) {
            cid = (Integer) f.get("cid");
            f.putAll(views.get(cid));
        }
        return fusers;
    }

    /**
     * 管理员日志
     * @param bookId
     * @param page
     * @return
     */
    public Page<CommentManageLog> getManageLogs(int bookId, Page<CommentManageLog> page) {
        page = managerService.getManageLogs(bookId, page);
        fillingMLog(page.getResult());
        return page;
    }

}
